#pragma once
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include"Common.hpp"

class InetAddr
{
public:
    InetAddr(){}
    InetAddr(struct sockaddr_in &addr) : _addr(addr)
    {
        SetAddr(_addr);
    }

    InetAddr(uint16_t port):_port(port)
    {
        memset(&_addr,0,sizeof(_addr));
        _addr.sin_port = htons(_port);
        _addr.sin_family = AF_INET;
        _addr.sin_addr.s_addr = INADDR_ANY;
    }
    InetAddr(const std::string ip,uint16_t port)
    :_port(port),_ip(ip)
    {
        memset(&_addr,0,sizeof(_addr));
        _addr.sin_port = htons(_port);
        _addr.sin_family = AF_INET;
        inet_pton(AF_INET,ip.c_str(),&_addr.sin_addr);
    }

    void SetAddr(struct sockaddr_in &addr)
    {
        _port = ntohs(_addr.sin_port);
        char ipbuffer[64];
        inet_ntop(AF_INET,&_addr.sin_addr,ipbuffer,sizeof(_addr));
        _ip = ipbuffer;
    }
    uint16_t Port() { return _port; }
    std::string Ip() { return _ip; }
    const struct sockaddr_in &GetSockaddr_in() { return _addr; }
    const struct sockaddr* GetNetAddr() { return CONV(&_addr); }
    socklen_t GetSocklen(){return sizeof(_addr);}
    std::string GetString() { return _ip + ":" + std::to_string(_port); }

    bool operator==(const InetAddr &a) { return _ip == a._ip && _port == a._port; }

    ~InetAddr() {}

private:
    uint16_t _port;
    std::string _ip;
    sockaddr_in _addr;
};